/*@cc_on 
var doc = document;
eval('var document = doc');
@*/
(function( $, undefined ){
$.extend($.expr[':'],{
	addedToDom: function( elm ){
		while ( elm.parentNode && elm.parentNode.tagName ) {
			elm = elm.parentNode;
		}
		return elm.tagName.toLowerCase() === "html";
	}
});

var
$doc = $(document),
Switcher = {
create:function( defState ){
	
	var
	state = typeof(defState) == "boolean" ? defState : true,
	key   = "switcher-state-changed" + (+new Date),
	fn    = function(){};
	
	fn.prototype = {
		isOn: function(){
			return state;
		},
		toggle:function( callback ){
			return this[state ? "off" : "on"]( callback );
		},
		on: function( callback ){
			state = true;
			$doc.trigger(key, [state]);
			(callback || function(){}).call(this, state);
			return this;
		},
		off: function( callback ){
			state = false;
			$doc.trigger(key, [state]);
			(callback || function(){}).call(this, state);
			return this;
		},
		bindStateChanged: function( handler ){
			$doc.bind(key, handler);
			return this;
		},
		unbindStateChanged: function( handler ){
			$doc.unbind(key, handler);
			return this;
		}
	};
	
	return new fn;	
}};

$.toggleBox = {
create:function( parentElement, options ){
	
	var
	opt = $.extend({
		key       : "togglebox",
		text      : "text:",
		state     : true,
		duration  : 300,
		easing    : "swing",
		raiseEvent: "after", //after or before
		width     : 0,
		label: {
			on : "▲",
			off: "▼"
		}
	},options),
	fn = function(){
		this.initialize.apply(this, arguments);
	},
	raiseEvent = opt.raiseEvent === "after" || opt.raiseEvent === "before" ? opt.raiseEvent : "after",
	pos = {};
	
	pos[true] = 0;
	
	fn.prototype = Switcher.create( opt.state );
	fn.prototype.initialize = function( parentElement ){
		
		var
		self = this,
		w = 0,
		$inner, $text, $label, $on, $off, $parent, isAdded;
		
		$inner = $((""
			+ "<div class='%key%-inner'>"
				+ "<div class='%key%-text-container'>"
					+ "<span class='%key%-text'>%text%</span>"
				+ "</div>"
				+ "<table cellSpacing='0' class='%key%-label-container'><tbody>"
					+ "<tr><td class='%key%-label-on'><span class='label'>%label_on%</span></td></tr>"
					+ "<tr><td class='%key%-label-off'><span class='label'>%label_off%</span></td></tr>"
				+ "</tbody></table>"
			+ "</div>")
				.replace( /%key%/g,       opt.key       )
				.replace( /%text%/g,      opt.text      )
				.replace( /%label_on%/g,  opt.label.on  )
				.replace( /%label_off%/g, opt.label.off ) );
		
		$text  = $( "span."  + opt.key + "-text",                   $inner );
		$label = $( "table." + opt.key + "-label-container",        $inner );
		$on    = $( "td."    + opt.key + "-label-on > span.label",  $label );
		$off   = $( "td."    + opt.key + "-label-off > span.label", $label );
		
		$inner.bind("click",({ 
			before: function(){
				self.toggle(function(state){
					$label.stop(true).animate({
						top: pos[ state ]
					}, opt.duration, opt.easing);
				});
			},
			after: function(){
				$label.stop(true).animate({
					top: pos[ !self.isOn() ]
				}, opt.duration, opt.easing, function(){
					self.toggle();
				});
			}
		})[ raiseEvent ]);
		
		this.$content = $(parentElement)
			.addClass(opt.key)
			.append($inner);
		
		//-=-=- ↓ set size -=-=-
		isAdded = this.$content.is(":addedToDom");
		
		if( !isAdded ){
			$parent = this.$content.parent();
			$(document.body).append(this.$content);
		}
		
		//set label width
		//get max width
		w = 0;
		$on.add( $off ).each(function(i, elm){
			w = Math.max( $(elm).width(), w );
		}).width(w);
		
		this.$content.width( (opt.width ? opt.width : $label.outerWidth() + $text.outerWidth()) );
		//set width end
		
		pos[false] = (-$on.parent().outerHeight());
		
		//init position
		$label.css({ top:pos[ this.isOn() ]});
		
		if( !isAdded && $parent.length ){
			$parent.append(this.$content);
		}
	}
	
	fn.prototype.performClick = function(){
		$inner.trigger("click", arguments);
		return this;
	}
	
	return new fn( parentElement, options );	
}};

$.fn.toggleBox = function(){
	var args = Array.prototype.slice.call(arguments), cb = [];
	this.each(function(){
		args.unshift(this);
		cb.push($.toggleBox.create.apply(null, args));
	});
	return cb;
};
})(jQuery);